package com.demo.webflux.spring5core.framework.webmvc;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.demo.webflux.spring5core.mock.HttpServletRequest;
import com.demo.webflux.spring5core.mock.HttpServletResponse;

/**自定义模板解析引擎，其核心方法是render，在render方法中完成对模板的渲染，最终返回浏览器能识别的字符串，通过response输出
 * @author zhangsulei
 *
 */
public class View {

	public static final String DEFAULT_CONTENT_TYPE = "text/html;charset=utf-8";
	private File viewFile;

	public View(File viewFile) {
		this.viewFile = viewFile;
	}

	public String getContentType() {
		return DEFAULT_CONTENT_TYPE;
	}

	public void render(Map<String, ?> model, HttpServletRequest req, HttpServletResponse resp) throws Exception {
		StringBuffer sb = new StringBuffer();
		RandomAccessFile ra = new RandomAccessFile(viewFile, "r");

		try {
			String line = null;
			while(null != (line = ra.readLine())) {
				line = new String(line.getBytes("ISO-8859-1"), "utf-8");
				Pattern pattern = Pattern.compile("\\$\\{(.*?)}", Pattern.CASE_INSENSITIVE);
				Matcher matcher = pattern.matcher(line);
				while(matcher.find()) {
					String paramName = matcher.group();
					paramName = paramName.replaceAll("\\$\\{|\\}", "");
					Object paramValue = model.get(paramName);
					if(null == paramValue) {
						continue;
					}
					// 要把${}中间的这个字符串取出来
					line = matcher.replaceFirst(makeStringForRegExp(paramValue.toString()));
					matcher = pattern.matcher(line);
				}
				sb.append(line);
			}
		} finally {
			ra.close();
		}
		resp.setCharacterEncoding("utf-8");
		resp.getWriter().write(sb.toString());
	}

	/**处理特殊字符
	 * @param string
	 * @return
	 */
	private String makeStringForRegExp(String str) {
		return str.replace("\\", "\\\\").replace("*", "\\*")
				.replace("+", "\\+").replace("|", "\\|")
				.replace("{", "\\{").replace("}", "\\}")
				.replace("(", "\\(").replace(")", "\\)")
				.replace("^", "\\^").replace("$", "\\$")
				.replace("[", "\\[").replace("]", "\\]")
				.replace("?", "\\?").replace(",", "\\,")
				.replace(".", "\\.").replace("&", "\\&");
	}

}
